#include "board.h"
#include "led.h"
#include "buzz.h"
#include "bmi088.h"
#include "adc128s.h"
#include "motor.h"
#include "encode.h"
#include "ssd1327.h"
#include "EC11.h"
#include "vl53l0x.h"
#include "hall.h"
#include "dma.h"
#include "zf_pwm.h"
#include "zf_uart.h"
#include "zf_delay.h"
#include "zf_gpio.h"
#include "zf_spi.h"
#include "zf_nvic.h"

Counter_type Counter;

void Board_Init(void)
{
    EAXFR = 1;     // 使能访问XFR
    CKCON = 0x00;  // 设置外部数据总线为最快
    WTST = 0;      // 设置程序代码等待参数，赋值为0可将CPU执行程序的速度设置为最快
    SET_P54_RESRT; // 使P54为复位引脚
    P_SW2 = 0x80;  // 开启特殊地址访问

    // 全设置为高阻模式
    P0M0 = 0x00;
    P0M1 = 0xFF;
    P1M0 = 0x00;
    P1M1 = 0xFF;
    P2M0 = 0x00;
    P2M1 = 0xFF;
    P3M0 = 0x00;
    P3M1 = 0xFF;
    P4M0 = 0x00;
    P4M1 = 0xFF;
    P5M0 = 0x00;
    P5M1 = 0xFF;
    P6M0 = 0x00;
    P6M1 = 0xFF;
    P7M0 = 0x00;
    P7M1 = 0xFF;

    // LED灯初始化
    LED_Init();
    LED_SetColor(COLORLESS);
    // 蜂鸣器初始化
    Buzz_Init();
    Buzz_ON();
    // 延时函数初始化
    delay_init();
    // 旋转编码器初始化
    EC11_Init();
    // 串口初始化
    // 注意，初始化不得给p30和p31赋初值，否则串口无法发送只得接收。因此要有针对性的赋初值
    gpio_mode(P3_0, GPIO);
    gpio_mode(P3_1, GPIO);
    uart_init(DEBUG_UART, DEBUG_UART_RX_PIN, DEBUG_UART_TX_PIN, DEBUG_UART_BAUD, DEBUG_UART_TIM);
    // DMA_Uart_Init();
    NVIC_SetPriority(UART1_IRQn, 3);
    // SPI初始化，写DMA失败了所以没用上
    spi_init(SPI_CH2, SPI_CH2_SCLK_P25, SPI_CH2_MOSI_P23, SPI_CH2_MISO_P24, 3, MASTER, SPI_SYSclk_DIV_4);
    HSSPI_CFG = 0x11;
    HSSPI_CFG2 = 0x20;
    P2SR &= 0xC7;
    P2DR &= 0xC7;
    // 陀螺仪初始化
    while (BMI088_init() != BMI088_NO_ERROR)
    {
        // 陀螺仪错误指示灯打开
        LED_SetColor(RED);
        delay_ms(50);
    }
    // 电磁传感器初始化
    ADC_Init();
    // 屏幕初始化
    OLED_Init();

    // TOF距离传感器初始化
    //     while (dl1a_init())
    //     {
    //     // 距离传感器错误指示灯打开
    //       LED_SetColor(YELLOW);
    //       delay_ms(50);
    //     }
    // 电机初始化
    Motor_Init();
    // 负压风扇初始化
    BLDC_Init();
    // 编码器初始化
    Enco_Init();
    // 霍尔传感器初始化
    Hall_Init();
    // 定时器四初始化，是副定时器用作计时
    pit_timer_ms(TIM_4, 1);
    // 定时器一初始化，是主定时器提供控制频率
    pit_timer_ms(TIM_1, 2);
    NVIC_SetPriority(TIMER1_IRQn, 2);
    // 原先控制频率在200hz。经过测试500hz没有问题，一千的话元素就不用识别了
    // 七月才有stc32f12k54的货。下一届参赛的可以试试，64Mhz主频带单精度FPU，DMA也用起来
    // 计时器结构体初始化
    Counter.Main = 0;
    Counter.MainSW = DISABLE;
    Counter.Tim4 = 0;
    Counter.Tim4SW = DISABLE;
    // 初始化完成，打开指示灯并关闭蜂鸣器
    Buzz_OFF();
    // 预热阶段指示灯
    LED_SetColor(YELLOW);
    // 打开全局中断开关
    EnableGlobalIRQ();
}

void DisableGlobalIRQ(void)
{
    EA = 0;
}

void EnableGlobalIRQ(void)
{
    EA = 1;
}
